package com.szcinda.service.dto.feeItem;

import com.szcinda.repository.FeeItem;
import com.szcinda.repository.FeeItemRepository;
import com.szcinda.repository.User;
import com.szcinda.repository.UserRepository;
import com.szcinda.service.PageResult;
import com.szcinda.service.SnowFlakeFactory;
import com.szcinda.service.dto.log.LogCreateDto;
import com.szcinda.service.dto.log.LogService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class FeeItemServiceImpl implements FeeItemService {

    private final FeeItemRepository feeItemRepository;
    private final SnowFlakeFactory snowFlakeFactory;
    private final UserRepository userRepository;
    private final LogService logService;

    public FeeItemServiceImpl(FeeItemRepository feeItemRepository, UserRepository userRepository, LogService logService) {
        this.feeItemRepository = feeItemRepository;
        this.userRepository = userRepository;
        this.logService = logService;
        this.snowFlakeFactory = SnowFlakeFactory.getInstance();
    }

    @Override
    public void create(FeeItemCreateDto createDto) {
        Assert.isTrue(!"报关费".equals(createDto.getName()) && !"报关联单费".equals(createDto.getName()), "不允许创建此[" + createDto.getName() + "]的费用科目");
        Assert.isTrue(!"运输费".equals(createDto.getName().trim()), "不允许创建此[" + createDto.getName().trim() + "]的费用科目");
        FeeItem record = feeItemRepository.findByName(createDto.getName());
        Assert.isTrue(record == null, "存在科目[" + createDto.getName() + "]的费用记录");
        FeeItem item = new FeeItem();
        item.setId(snowFlakeFactory.nextId("FE"));
        item.setName(createDto.getName().trim());
        feeItemRepository.save(item);
        User user = userRepository.findById(createDto.getOpId());
        LogCreateDto logCreateDto = new LogCreateDto(user.getId(), user.getNickName(), "新增费用科目", item.getName());
        logService.create(logCreateDto);
    }

    @Override
    public void delete(String id, String userId) {
        FeeItem feeItem = feeItemRepository.findById(id);
        feeItemRepository.delete(feeItem);
        User user = userRepository.findById(userId);
        LogCreateDto createDto = new LogCreateDto(user.getId(), user.getNickName(), "删除费用科目", feeItem.getName());
        logService.create(createDto);
    }

    @Override
    public PageResult<FeeItem> query(FeeItemQueryDto params) {
        Specification<FeeItem> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(params.getName())) {
                Predicate site = criteriaBuilder.like(root.get("name").as(String.class), params.getName().trim() + "%");
                predicates.add(site);
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        });
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = new PageRequest(params.getPage() - 1, params.getPageSize(), sort);
        Page<FeeItem> details = feeItemRepository.findAll(specification, pageable);
        // 过滤是运费的费用明细
        return PageResult.of(details.getContent().stream().filter(feeItem -> !feeItem.getName().equals("运输费")).collect(Collectors.toList()), params.getPage(), params.getPageSize(), details.getTotalElements());
    }

    @Override
    public List<FeeItem> getAll() {
        List<FeeItem> feeItems = feeItemRepository.findAll();
//        if (feeItems != null) {
//            feeItems = feeItems.stream().filter(feeItem -> !feeItem.getName().equals("运输费")).collect(Collectors.toList());
//        }
        return feeItems;
    }
}
